package object2D;

import byggeTegner.ByggeTegner;
import byggeTegner.DrawPanel;
import context.*;

import geometry2D.MetricPoint2D;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import model2D.Model2D;
import util.FillStyle;
import util.StrokeStyle;
import util.Util;
import util.Util2;


public class LinjalObject extends Object2D implements Context.Constants
{ //private static final boolean DEBUG=true; // Overriding Context.Constants.DEBUG
  static final String TAG="object2D.LinjalObject";
  static final String TYPE="Linjal";
  private static final int KOTER=0;
  private static final int VERTICAL=1;
  private static final int HORISONTAL=2;
  private static final double diffLIM=0.35;//0.30;

  private int kind;
  private double length;
  private double koteBase;
  private double[] dist;

  
  public LinjalObject(Model2D objectModel,String ident,MetricPoint2D p0,double length) throws JSONException
  { super(objectModel,ident);
    add(p0);
    this.length=length;
  }
  
  public LinjalObject(Model2D objectModel,JSONObject jsonObject) throws JSONException
  { super(objectModel,jsonObject.getString("id"));
    if(DEBUG) Log.d(TAG,"decodeSVG: jsonObject="+jsonObject);
    this.fill=new FillStyle(jsonObject);
    this.stroke=new StrokeStyle(jsonObject);
    add(new MetricPoint2D(jsonObject.getJSONArray("p1")));
    this.kind=jsonObject.getInt("kind");
    this.length=jsonObject.getDouble("length");
    this.koteBase=jsonObject.getDouble("koteBase");
    JSONArray d=jsonObject.getJSONArray("dist");
    //if(DEBUG) Log.d(TAG,"PathObject.decodeSVG: name="+name+", d="+d);
    this.dist=new double[d.length()];
    for(int i=0;i<d.length();i++) dist[i]=d.getDouble(i);
    
  }

  public JSONObject toJSONObject() throws JSONException
  { JSONObject jsonObject=new JSONObject();
    jsonObject.put("type",TYPE);
    jsonObject.put("id",getIdent());
    jsonObject.put("p1",getMapLocation(0).encode());
    jsonObject.put("kind",kind);
    jsonObject.put("length",length);
    jsonObject.put("koteBase",koteBase);
    jsonObject.put("dist",dist);
    jsonObject.put("fill",fill.encode());
    jsonObject.put("stroke",stroke.encode());
	return(jsonObject);
  }

  // *************************************************************************
  // *** METHOD: paint
  // *************************************************************************
  public void paint(Graphics2D g,DrawPanel drawPanel)
  { g.setStroke(stroke.getBasicStroke(drawPanel.getPrintScale()));
    g.setColor(stroke.getColor());
    g.setFont(font.getFont(drawPanel));
    switch(kind)
	{ case KOTER: paintKoter(g,drawPanel); break;
	  case VERTICAL: paintVertikal(g,drawPanel); break;
	  case HORISONTAL: paintHorisontal(g,drawPanel); break;
	}
  }

  
  public void setKoter(double koteBase,double[] dist) throws JSONException
  { this.koteBase=koteBase;  
	this.dist=dist;
	this.kind=KOTER;
  }
  
  private void paintKoter(Graphics2D g,DrawPanel drawPanel)
  { if(TEGN_LINJALER)
    { MetricPoint2D p0=getMapLocation(0);
      double d10=0.10;
      double heightL=length;
      double xL=p0.getX();
      double yL=p0.getY();
      Util.drawLine(g,xL,yL-2*d10,xL,yL+heightL+2*d10);
      double prevDist=0;
      for(int i=0;i<dist.length;i++)
      { double dd=dist[i];
        Util.drawLine(g,xL-d10,yL+dd,xL+d10,yL+dd); // Tverrlinje etter 'dist[i]'
        double diff=dd-prevDist;
        if(diff>diffLIM || i==(dist.length-1))
        {  
          if(diff>diffLIM) Util.label(g,""+(int)(diff*100+0.5),xL,yL+(prevDist+diff/2));
          double kote=koteBase+length-prevDist;
          int dec=(int)(kote*10+0.5);
          int pre=dec/10;
          int pst=dec-pre*10;
          Util.label(g,"Kote "+pre+'.'+pst,xL+1.30,yL+(prevDist));
        }
        prevDist=dd;
      }
    }    
  }
  
  public void setVertikal(double[] dist) throws JSONException
  { this.dist=dist;
	this.kind=VERTICAL;
  }
  
  private void paintVertikal(Graphics2D g,DrawPanel drawPanel)
  { if(TEGN_LINJALER)
    { MetricPoint2D p0=getMapLocation(0);
      double d10=0.10;
      double heightL=length;
      double xL=p0.getX();
      double yL=p0.getY();
      Util.drawLine(g,xL,yL-2*d10,xL,yL+heightL+2*d10);
      double prevDist=0;
      for(int i=0;i<dist.length;i++)
      { double dd=dist[i];
        Util.drawLine(g,xL-d10,yL+dd,xL+d10,yL+dd); // Tverrlinje etter 'dist[i]'
        double diff=dd-prevDist;
        if(diff>diffLIM) Util.label(g,""+(int)(diff*100+0.5),xL,yL+(prevDist+diff/2));
        prevDist=dd;
      }
    }    
  }
  
  public void setHorisontal(double[] dist) throws JSONException
  { this.dist=dist;
	this.kind=HORISONTAL;
  }
  
  private void paintHorisontal(Graphics2D g,DrawPanel drawPanel)
  { if(TEGN_LINJALER)
    { MetricPoint2D p0=getMapLocation(0);
      double d10=0.10;
      double widthL=length;
      double xL=p0.getX();
      double yL=p0.getY();
      Util.drawLine(g,xL-2*d10,yL,xL+widthL+2*d10,yL);
      double prevDist=0;
      for(int i=0;i<dist.length;i++)
      { double dd=dist[i];
        Util.drawLine(g,xL+dd,yL-d10,xL+dd,yL+d10); // Tverrlinje etter 'dist[i]'
        double diff=dd-prevDist;
        if(diff>diffLIM) Util.label(g,""+(int)(diff*100+0.5),xL+(prevDist+diff/2),yL);
        prevDist=dd;
      }    
    }
  }
  

  // ****************************************************************
  // *** INNER CLASS: EditGeneralPanel
  // ****************************************************************
  public JPanel getEditGeneralPanel(String title)
  { return(new EditGeneralPanel(title)); }
  private class EditGeneralPanel extends JPanel
  { static final long serialVersionUID=0; // AD'HOC
    private JTextField identField;
    private JButton strokeButton;
    private JButton fillButton;
      
    public void paint(Graphics g)
    { if(DEBUG) Log.d(TAG,"EditGeneralPanel.paint: ");
      identField.setText(getIdent());
      strokeButton.setBackground(stroke.getColor());
      fillButton.setBackground(fill.getColor());
  	  super.paint(g);  
    }
    	
    public EditGeneralPanel(String title)
    { setBorder(Util2.getTitleBorder(title));
      if(numberOfPoints()==4) // Firkant
      { setPreferredSize(new Dimension(350,120));//140));
        setLayout(new GridLayout(6,2));
      }
      else
      { setPreferredSize(new Dimension(350,120));
        setLayout(new GridLayout(5,2));
      }
      add(new JLabel("       Ident:"));
      identField=new JTextField(getIdent());
      identField.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setIdent(identField.getText()); }
      });
      add(identField);
      fillButton=addEditFillButton(this,true);
      strokeButton=addEditStrokeButton(this,true);
        
      JCheckBox closedBox=new JCheckBox("Closed Path",null,getClosedPath());
      closedBox.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setClosedPath(!getClosedPath());
          ByggeTegner.repaint();        	
        }
      });
      add(closedBox);
      add(new JLabel(" ")); // Space only
      
    }
  }

}
